#include <stdio.h>
#include <ulog/ulog.h>
#include "iic_function.h"
#include "camera_config.h"
#include "drv_isp.h"
#include "soc.h"
#include "pin_name.h"
#include "sc2355_drv.h"
#include "drv_gpio.h"
//#include "image_proc.h"
#include "reg_deal.h"
//#include "test_hist.h"
#include "sc2355_drv.h"

#define SENSOR_MODULE "sc2355"

static i2c_dev_t i2c_sc2355_left;
static i2c_dev_t i2c_sc2355_right;
uint32_t g_sc2355_configed = 0;
extern gpio_pin_handle_t gpio_pin_handle;
sc2355_config_t g_sc2355_config = SC2355_NO_NEED_CONFIG;
typedef enum 
{
    CFG_MODE_NONE = 0,		
    CFG_MODE_RGB_1080P_YUV,
    CFG_MODE_RGB_720P_YUV,
    CFG_MODE_RGB_640X360_RGB,
    CFG_MODE_IR_720P_YUV,
    CFG_MODE_IR_720P_RAW10,
    CFG_MODE_IR_640x360_RAW,    
	CFG_MODE_IR_1080P_RAW10,
}SENSOR_CFG_MODE_E;


#define AOGPIO_BASE						0xFFF02000
#define GPIO_SWPORTA_DR					0x0
#define GPIO_SWPORTA_DDR				0x4

static void set_aogpio_high(uint8_t aogpio)
{
	uint32_t data;
	data = rd(AOGPIO_BASE + GPIO_SWPORTA_DDR);
	wr(AOGPIO_BASE + GPIO_SWPORTA_DDR, data | (1 << aogpio));
	data = rd(AOGPIO_BASE + GPIO_SWPORTA_DR);
	wr(AOGPIO_BASE + GPIO_SWPORTA_DR, data | (1 << aogpio));
}

static void set_aogpio_low(uint8_t aogpio)
{
	uint32_t data;
	data = rd(AOGPIO_BASE + GPIO_SWPORTA_DDR);
	wr(AOGPIO_BASE + GPIO_SWPORTA_DDR, data | (1 << aogpio));
	data = rd(AOGPIO_BASE + GPIO_SWPORTA_DR);
	wr(AOGPIO_BASE + GPIO_SWPORTA_DR, data & (~(1 << aogpio)));
}

static void camera_io_out32(uint32_t addr, uint32_t value)			//write
{
	volatile uint32_t *ptr = (volatile uint32_t *)(addr);
	//printf("write: addr=0x%x, data=0x%x\n", addr, value);
	*ptr = value;
}

static uint32_t camera_io_in32(uint32_t addr)						//read
{
	volatile uint32_t *ptr = (volatile uint32_t *)(addr);
	//printf("read:  addr=0x%x, data=0x%x\n", ptr, *ptr);
	
	return *ptr;
}

static void camera_io_rstn_init(uint8_t index)
{
	uint32_t reg_val;

	reg_val = camera_io_in32(CSKY_AOGPIO_BASE + 0x04);
	reg_val |= (0x1 << index);
	
	camera_io_out32(CSKY_AOGPIO_BASE + 0x04, reg_val);
}

void camera_io_rstn_set(uint8_t index, bool level)
{
	uint32_t reg_val;

	reg_val = camera_io_in32(CSKY_AOGPIO_BASE + 0x00); 
	if (level)
		reg_val |= (0x1 << index);
	else
		reg_val &= ~(0x1 << index);

	camera_io_out32(CSKY_AOGPIO_BASE + 0x00, reg_val);
}

void sensorHwReset( int sensor_idx ) {
    camera_io_rstn_init(sensor_idx);
    camera_io_rstn_set(sensor_idx, true);    aos_msleep(1);
    camera_io_rstn_set(sensor_idx, false);   aos_msleep(1);
    camera_io_rstn_set(sensor_idx, true);    aos_msleep(1);
}

void sensorHwReset_5( int sensor_idx ){
    camera_io_rstn_init(sensor_idx);
    camera_io_rstn_set(sensor_idx, false);   aos_msleep(1);
}

//cleaned_0x05_SC2355_MIPI_24Minput_1lane_10bit_720Mbps_1608x1208_30fps.ini

//cleaned_0x05_SC2355_DVP_24Minput_37.125Mpclk_10bit_1280x720_30fps.ini
regval_list sc2355_1600x1200_raw10[] = {
{0x0103,0x01},
{0x0100,0x00},
{0x36e9,0x80},
{0x36ea,0x0f},
{0x36eb,0x25},
{0x36ed,0x04},
{0x36e9,0x01},
{0x301f,0x05},
// {0x3031,0x08}, 
{0x3200,0x00},
{0x3201,0x00},
{0x3202,0x00},
{0x3203,0x00},
{0x3204,0x06},
{0x3205,0x4b},
{0x3206,0x04},
{0x3207,0xbb},
{0x3208,0x06},
{0x3209,0x48},
{0x320a,0x04},
{0x320b,0xb8},
{0x3210,0x00},
{0x3211,0x02},
{0x3212,0x00},
{0x3213,0x02},
{0x3248,0x04},
{0x3253,0x0a},
{0x3301,0xff},
{0x3302,0xff},
{0x3303,0x10},
{0x3306,0x28},
{0x3307,0x02},
{0x330a,0x00},
{0x330b,0xb0},
{0x3318,0x02},
{0x3320,0x06},
{0x3321,0x02},
{0x3326,0x12},
{0x3327,0x0e},
{0x3328,0x03},
{0x3329,0x0f},
{0x3364,0x4f},
{0x33b3,0x40},
{0x33f9,0x2c},
{0x33fb,0x38},
{0x33fc,0x0f},
{0x33fd,0x1f},
{0x349f,0x03},
{0x34a6,0x01},
{0x34a7,0x1f},
{0x34a8,0x40},
{0x34a9,0x30},
{0x34ab,0xa6},
{0x34ad,0xa6},
{0x3622,0x60},
{0x3623,0x40},
{0x3624,0x61},
{0x3625,0x08},
{0x3630,0xa8},
{0x3631,0x84},
{0x3632,0x90},
{0x3633,0x43},
{0x3634,0x09},
{0x3635,0x82},
{0x3636,0x48},
{0x3637,0xe4},
{0x3641,0x22},
{0x3670,0x0f},
{0x3674,0xc0},
{0x3675,0xc0},
{0x3676,0xc0},
{0x3677,0x86},
{0x3678,0x88},
{0x3679,0x8c},
{0x367c,0x01},
{0x367d,0x0f},
{0x367e,0x01},
{0x367f,0x0f},
{0x3690,0x63},
{0x3691,0x63},
{0x3692,0x73},
{0x369c,0x01},
{0x369d,0x1f},
{0x369e,0x8a},
{0x369f,0x9e},
{0x36a0,0xda},
{0x36a1,0x01},
{0x36a2,0x03},
{0x3900,0x0d},
{0x3904,0x06},
{0x3905,0x98},
{0x391b,0x81},
{0x391c,0x10},
{0x391d,0x19},
{0x3933,0x81},
{0x3934,0x82},
{0x3940,0x5d},
{0x3942,0x01},
{0x3943,0x82},
{0x3949,0xc8},
{0x394b,0x64},
{0x3952,0x02},
{0x3e00,0x00},
{0x3e01,0x4d},
{0x3e02,0xe0},
{0x4502,0x34},
{0x4509,0x30},
{0x450a,0x71},
{0x0100,0x01},

};
regval_list sc2355_jt_600X800_raw10[] = {
{0x0103,0x01},
{0x0100,0x00},
{0x36e9,0x80},
{0x36ea,0x0f},
{0x36eb,0x25},
{0x36ed,0x04},
{0x36e9,0x01},
{0x301f,0x01},
{0x3221,0x06},
{0x3248,0x02},
{0x3253,0x0a},
{0x3301,0xff},
{0x3302,0xff},
{0x3303,0x10},
{0x3306,0x28},
{0x3307,0x02},
{0x330a,0x00},
{0x330b,0xb0},
{0x3318,0x02},
{0x3320,0x06},
{0x3321,0x02},
{0x3326,0x12},
{0x3327,0x0e},
{0x3328,0x03},
{0x3329,0x0f},
{0x3364,0x0f},
{0x33b3,0x40},
{0x33f9,0x2c},
{0x33fb,0x38},
{0x33fc,0x0f},
{0x33fd,0x1f},
{0x349f,0x03},
{0x34a6,0x01},
{0x34a7,0x1f},
{0x34a8,0x40},
{0x34a9,0x30},
{0x34ab,0xa6},
{0x34ad,0xa6},
{0x3622,0x60},
{0x3625,0x08},
{0x3630,0xa8},
{0x3631,0x84},
{0x3632,0x90},
{0x3633,0x43},
{0x3634,0x09},
{0x3635,0x82},
{0x3636,0x48},
{0x3637,0xe4},
{0x3641,0x22},
{0x3670,0x0e},
{0x3674,0xc0},
{0x3675,0xc0},
{0x3676,0xc0},
{0x3677,0x86},
{0x3678,0x88},
{0x3679,0x8c},
{0x367c,0x01},
{0x367d,0x0f},
{0x367e,0x01},
{0x367f,0x0f},
{0x3690,0x43},
{0x3691,0x43},
{0x3692,0x53},
{0x369c,0x01},
{0x369d,0x1f},
{0x3900,0x0d},
{0x3904,0x06},
{0x3905,0x98},
{0x391b,0x81},
{0x391c,0x10},
{0x391d,0x19},
{0x3949,0xc8},
{0x394b,0x64},
{0x3952,0x02},
{0x3e00,0x00},
{0x3e01,0x4d},
{0x3e02,0xe0},
{0x4502,0x34},
{0x4509,0x30},
{0x0100,0x01},
};
regval_list sc2355_strobe_init[] = {
	//@@ Strobe Control init example �?sc2355
{0x3006, 0x0c}, //;08 ; enable 
{0x3210, 0x04}, //;10 ; disable GPIO trigger mode
{0x3007, 0x02}, //
{0x301c, 0xf2}, //;22 ;enable the clock for group write, [1]rst_grp 
{0x3020, 0x20}, //;20 ; strobe logic always on 
{0x3025, 0x02}, //
{0x382c, 0x09},
{0x382d, 0x9a},
{0x3920, 0xff}, //
{0x3923, 0x00}, //; delay 
{0x3924, 0x00}, //; 
{0x3925, 0x00}, //; width 
{0x3926, 0x00}, //
{0x3927, 0x00}, //
{0x3928, 0x80}, //
{0x392b, 0x00}, //
{0x392c, 0x00}, //
{0x392d, 0x05}, //;02 ;=HTS
{0x392e, 0x8e}, //;d8 
{0x392f, 0xcb}, //
{0x38b3, 0x07}, //
{0x3885, 0x07}, //
{0x382b, 0x5a}, //
{0x3670, 0x68}, //


	
};

regval_list sc2355_strobe_time[] = {
	//@@Below need program every time during exposure update strobe 10ms
	//;Exp 1, Gain 1x
	//;Exp 1, Gain 1x
	{0x3208,0x00},//;
	// {0x3501,0x07},//;0f; exp
	// {0x3502,0x66},//;10
	{0x3501,0x03},
	{0x3502,0xB6},

	{0x3508,0x00},//; gain
	// {0x3509,0x20},//
	{0x3509,0x10},//
	// {0x3927,0x00},//;00
	// {0x3928,0x76},//; strobe width 10ms
	// {0x3929,0x03},//; strobe start point is VTS �?Texposure �?7 �?Tnegative, 
	// {0x392A,0x5A},// e.g. VTS = 0x3d8, Texposure = 0x58, if Tnegative = 1, then R3929/2a = 0x378
	{0x3927,0x00},//;00
	{0x3928,0x3B},//; strobe width 10ms
	{0x3929,0x03},//; strobe start point is VTS �?Texposure �?7 �?Tnegative, 
	{0x392A,0x95},// e.g. VTS = 0x3d8, Texposure = 0x58, if Tnegative = 1, then R3929/2a = 0x378
	{0x3208,0x10},//;
	{0x3208,0xA0},//

};

const  regval_list sc2355_1600x1200_master_read[] = {
	{0x3001,0x00},
};


const  regval_list sc2355_sw_standby[] = {
	{0x0100 , 0x00},
};

const  regval_list sc2355_streaming[] = {
	{0x0100 , 0x01},
};


int sc2355_mode_config(sensor_mode_t mode)
{	
	int ret = 0;
	// printf("%s >>>>  %d, mode %d \n",__func__, __LINE__, mode);
#if 1
	if (STANDBY == mode) {
		ret = iic_write_array(&i2c_sc2355_left, (struct regval_list *)sc2355_sw_standby, ARRAY_SIZE(sc2355_sw_standby));
		if (ret < 0) {
			return -1;
		}
	} else {
		ret = iic_write_array(&i2c_sc2355_left, (struct regval_list *)sc2355_streaming, ARRAY_SIZE(sc2355_streaming));
		if (ret < 0) {
			return -1;
		}
	}
#else
	if (STANDBY == mode) {
		ret = iic_write_array(&i2c_sc2355_right, (struct regval_list *)sc2355_sw_standby, ARRAY_SIZE(sc2355_sw_standby));
		if (ret < 0) {
			return -1;
		}
	} else {
		ret = iic_write_array(&i2c_sc2355_right, (struct regval_list *)sc2355_streaming, ARRAY_SIZE(sc2355_streaming));
		if (ret < 0) {
			return -1;
		}
	}

#endif
	return 0;
}

int sc2355_right_mode_config(sensor_mode_t mode)
{	
	int ret = 0;
	printf("%s >>>>  %d, mode %d \n",__func__, __LINE__, mode);

	if (STANDBY == mode) {
		ret = iic_write_array(&i2c_sc2355_right, (struct regval_list *)sc2355_sw_standby, ARRAY_SIZE(sc2355_sw_standby));
		if (ret < 0) {
			return -1;
		}
	} else {
		ret = iic_write_array(&i2c_sc2355_right, (struct regval_list *)sc2355_streaming, ARRAY_SIZE(sc2355_streaming));
		if (ret < 0) {
			return -1;
		}
	}
}

static int sc2355_check_id(i2c_dev_t *i2c)
{
    int ret = 0;
    uint8_t data = 0;

    printf("check sc2355 id: \n");
    
    ret = iic_read(i2c,  SC2355_REG_CHIPID_H, &data);
    printf("H %02x \n",data);
    if (ret < 0 || data != 0xeb)
        return -1;
    ret = iic_read(i2c, SC2355_REG_CHIPID_L, &data);
    printf("L %02x \n",data);
   	if (ret < 0 || data != 0x2c)
        return -1;

    return ret;
}




int sc2355_init_strobe(void)
{
	int ret = 0;

	ret = iic_write_array(&i2c_sc2355_left, (struct regval_list *)sc2355_strobe_init, ARRAY_SIZE(sc2355_strobe_init));
	if (ret < 0) {
		return -1;
	}

	return 0;
}

int sc2355_config_strobe_time(void)
{
	int ret = 0;

	ret = iic_write_array(&i2c_sc2355_left, (struct regval_list *)sc2355_strobe_time, ARRAY_SIZE(sc2355_strobe_time));
	if (ret < 0) {
		return -1;
	}

	return 0;

}

int sc2355_strobe_config(void)
{
	int ret = 0;

	ret = sc2355_init_strobe();
	if (ret < 0) {
		printf("sc2355 init strobe err!\n");
		return -1;
	}

	ret = sc2355_config_strobe_time();
	if (ret < 0) {
		printf("sc2355 config strobe time err!\n");
		return -1;
	}

	return 0;
}

int sc2355_init_left(i2c_dev_t *i2c, uint32_t dev_addr)
{
   	memcpy(&i2c_sc2355_left, i2c, sizeof(i2c_dev_t));
    i2c_sc2355_left.config.dev_addr = dev_addr;
    //Check the id of camera
   	int ret = sc2355_check_id(&i2c_sc2355_left);
    if (ret < 0) {
        printf("camera sc2355 ir check id failed !!! \n");
        return ret;
    }
    return ret;
}

int sc2355_init_right(i2c_dev_t *i2c, uint32_t dev_addr)
{
   	memcpy(&i2c_sc2355_right, i2c, sizeof(i2c_dev_t));
    i2c_sc2355_right.config.dev_addr = dev_addr;
    //Check the id of camera
   	int ret = sc2355_check_id(&i2c_sc2355_right);
    if (ret < 0) {
        printf("camera sc2355 rgb check id failed !!! \n");
        return ret;
    }
    return ret;
}

int32_t sc2355_config_right(imageFormat_t cfg)
{
	int32_t ret = 0;

	if( R_1600x1200 == cfg.res && RAW10 == cfg.format)
	{
        printf("sc2355 config rgb enter \n");
		ret = iic_write_array(&i2c_sc2355_right, (struct regval_list *)sc2355_1600x1200_raw10, ARRAY_SIZE(sc2355_1600x1200_raw10));
		if (ret < 0) {
			return -1;
		}
	}

	if( R_720P == cfg.res && RAW10 == cfg.format)
	{
		ret = iic_read_array(&i2c_sc2355_right, (struct regval_list *)sc2355_jt_600X800_raw10, ARRAY_SIZE(sc2355_jt_600X800_raw10));
		if (ret < 0) {
			return -1;
		}
	}
#if 0	
	else if(R_720P == cfg.res && RAW8 == cfg.format)
	{
		ret = iic_write_array(&i2c_sc2355_right, (struct regval_list *)sc2355_jt_600X800_raw10, ARRAY_SIZE(sc2355_jt_600X800_raw10));
		if (ret < 0) {
			return -1;
		}
    }
#endif 


#if 0 //tmp remove
	ret = sc2355_strobe_config();
	if (ret < 0)
		return -1;
#endif 
	return ret;
}

int32_t sc2355_config_left(imageFormat_t cfg)
{
	int32_t ret = 0;

	if( R_1600x1200 == cfg.res && RAW10 == cfg.format)
	{
        printf("sc2355 config ir enter \n");
		ret = iic_write_array(&i2c_sc2355_left, (struct regval_list *)sc2355_1600x1200_raw10, ARRAY_SIZE(sc2355_1600x1200_raw10));
		if (ret < 0) {
			return -1;
		}
	}

#if 1	
	else if(R_720P == cfg.res && RAW8 == cfg.format)
	{
		ret = iic_write_array(&i2c_sc2355_left, (struct regval_list *)sc2355_jt_600X800_raw10, ARRAY_SIZE(sc2355_jt_600X800_raw10));
		if (ret < 0) {
			return -1;
		}
    }
#endif 

#if 0 //tmp remove
	ret = sc2355_strobe_config();
	if (ret < 0)
		return -1;
#endif 
	return ret;
}

int sc2355_switch_exposure_para(exposure_scene_t scene)
{
    int ret = 0;
    static regval_list expo_arg[] = { 
        {0x3501,0x4A},	//expo H		
        {0x3502,0x00},  //expo L
        {0x3508,0x02},
        {0x3509,0x80},  //gain
    };

    if (EXPOSURE_PARA_OUTDOOR == scene) {
        // expo 3ms
		expo_arg[0].data = 0x20;
		expo_arg[1].data = 0x00;
		expo_arg[2].data = 0x00;
		expo_arg[3].data = 0x80;

    } else {
        // expo 10ms
        expo_arg[0].data = 0x3e;
        expo_arg[1].data = 0xa0;
        expo_arg[2].data = 0x02;
		expo_arg[3].data = 0x80;
    }

	LOGI(SENSOR_MODULE, "cur_scene %s", scene == EXPOSURE_PARA_INDOOR ? "indoor" : "outdoor");
    LOGI(SENSOR_MODULE, "expo_h:%02x, expo_l: %02x, gain:%02x\n", expo_arg[0].data, expo_arg[1].data, expo_arg[2].data);
	//printf( "cur_scene %s", scene == EXPOSURE_PARA_INDOOR ? "indoor" : "outdoor");
    //printf( "expo_h:%02x, expo_l: %02x, gain:%02x\n", expo_arg[0].data, expo_arg[1].data, expo_arg[2].data);

    ret = iic_write_array(&i2c_sc2355_left, (struct regval_list *)expo_arg, ARRAY_SIZE(expo_arg));
    if(ret != 0) {
        LOGI(SENSOR_MODULE, " 2732 expo config error:%d \n", ret);
    }
    return ret; 
}

int sc2355_set_exposure_para(regval_list *expo_arg)
{
    int ret = 0;

    ret = iic_write_array(&i2c_sc2355_left, (struct regval_list *)expo_arg, 4);
    if(ret != 0) {
        LOGI(SENSOR_MODULE, " 2732 expo config error:%d \n", ret);
    }
	
    return ret; 
}


int sc2355_get_exposure_para(regval_list *expo_arg)
{
    int ret = 0;

    ret = iic_read_array(&i2c_sc2355_left, (struct regval_list *)expo_arg, 4);
    if(ret != 0) {
        LOGI(SENSOR_MODULE, " 2732 expo config error:%d \n", ret);
    }
	
    return ret; 
}

int sc2355_rgb_get_exposure_para(regval_list *expo_arg)
{
    int ret = 0;

    ret = iic_read_array(&i2c_sc2355_right, (struct regval_list *)expo_arg, 4);
    if(ret != 0) {
        LOGI(SENSOR_MODULE, " 2732 expo config error:%d \n", ret);
    }
	
    return ret; 
}



int sc2355_set_spk_exposure_para(exposure_scene_t scene)
{
    int ret = 0;

	return ret;
	
    static regval_list expo_arg[] = { 
        {0x3501,0},	//expo H		
        {0x3502,0},  //expo L
        {0x3509,0},  //gain
    };

    if (EXPOSURE_PARA_OUTDOOR == scene) {
        // expo 2ms
        expo_arg[0].data = 0x03;
        expo_arg[1].data = 0xb6;
        expo_arg[2].data = 0x10;

    } else {
        // expo 2ms
        expo_arg[0].data = 0x03;
        expo_arg[1].data = 0xb6;
        expo_arg[2].data = 0x80;
    }

    LOGI(SENSOR_MODULE, "expo_h:%02x, expo_l: %02x, gain:%02x\n", expo_arg[0].data, expo_arg[1].data, expo_arg[2].data);

    ret = iic_write_array(&i2c_sc2355_left, (struct regval_list *)expo_arg, ARRAY_SIZE(expo_arg));
    if(ret != 0) {
        LOGE(SENSOR_MODULE, " 2355 expo config error:%d \n", ret);
    }
    return ret; 
}

int set_sc2355_reglist(regval_list reglist[], uint32_t reglist_len)
{
    int ret = 0;

    ret = iic_write_array(&i2c_sc2355_left, (struct regval_list *)reglist, reglist_len);
    if(ret != 0) {
        LOGE(SENSOR_MODULE, " 2355 expo config error:%d \n", ret);
    }
    return ret; 
}

int32_t sc2355_config_reglist(uint32_t ir_mode, uint32_t addr, uint32_t data)
{
    uint32_t array_size = 0;
#if 0    
	if (CFG_MODE_IR_640x360_RAW == ir_mode) {
		array_size = ARRAY_SIZE(sc2355_1280x720_raw8);
		config_reglist(sc2355_1280x720_raw8, array_size, addr, data);
	} else if (CFG_MODE_IR_720P_RAW10 == ir_mode) {
		array_size = ARRAY_SIZE(sc2355_jt_600X800_raw10);
	config_reglist(sc2355_1280x720_raw8, array_size, addr, data);
	} else {
		printf("unkown ir mode\n");
		return -1;
	}
#else 
if (CFG_MODE_IR_1080P_RAW10 == ir_mode) {
		array_size = ARRAY_SIZE(sc2355_jt_600X800_raw10);
		config_reglist(sc2355_jt_600X800_raw10, array_size, addr, data);
	}

#endif
    return 0;
}


uint32_t sc2355_lookup_reg(uint32_t ir_mode, uint32_t addr)
{
    uint32_t array_size = 0;
    uint32_t ret = 0;
#if 0
	if (CFG_MODE_IR_640x360_RAW == ir_mode) {
		array_size = ARRAY_SIZE(sc2355_1280x720_raw8);
			ret = lookup_reg(sc2355_1280x720_raw8, array_size, addr);
	} else if (CFG_MODE_IR_720P_RAW10 == ir_mode) {
		array_size = ARRAY_SIZE(sc2355_jt_600X800_raw10);
		ret = lookup_reg(sc2355_1280x720_raw8, array_size, addr);
	}
#else
	
			array_size = ARRAY_SIZE(sc2355_jt_600X800_raw10);
			ret = lookup_reg(sc2355_jt_600X800_raw10, array_size, addr);
	

#endif 
    return ret;
}


regval_list sc2355_test[] = {
    {0x301f,0x00},
    {0x3107,0x00},
	{0x3108,0x00},
	{0x3031,0x00},
	{0x3037,0x00},
	{0x3650,0x00},
	{0x3221,0x00},
	{0x320e,0x00},
	{0x320f,0x00},
	{0x320c,0x00},
	{0x320d,0x00},

};

int sc2355_get_test_para()
{
    int ret = 0;

    ret = iic_read_array(&i2c_sc2355_right, (struct regval_list *)sc2355_test, ARRAY_SIZE(sc2355_test));
    if(ret != 0) {
        LOGI(SENSOR_MODULE, " 2355 expo config error:%d \n", ret);
    }
	
    return ret; 
}



#if 1



static const uint16_t gau16GainIndex[160] = {
    1024, 1056, 1089, 1120, 1152, 1184, 1217, 1248, 1280, 1312, 1345, 1376, 1408, 1440, 1473, 1504, 1536, 1568, 1601, 1632, 1664, 1696, 1729, 1760, 1792, 1824, 1857, 1888, 1920, 1952, 1985, 2016,
    2048, 2113, 2176, 2241, 2304, 2369, 2432, 2497, 2560, 2640, 2688, 2753, 2816, 2877, 2944, 3011, 3072, 3133, 3200, 3267, 3328, 3389, 3456, 3523, 3584, 3645, 3712, 3779, 3840, 3901, 3968, 4035,
    4096, 4229, 4352, 4485, 4608, 4741, 4864, 4997, 5120, 5253, 5376, 5509, 5632, 5765, 5888, 6021, 6144, 6277, 6400, 6533, 6656, 6789, 6912, 7045, 7168, 7301, 7424, 7557, 7680, 7813, 7936, 8069, 
	8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, 10496, 10752, 11008, 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13312, 13568, 13824, 14080, 14336, 14592, 14848, 15104, 15360, 15616, 15872, 16128, 
	16384, 16896, 17408, 17920, 18432, 18944, 19456, 19968, 20480, 20992, 21504, 22016, 22528, 23040, 23552, 24064, 24576, 25088, 25600, 26112, 26624,27136, 27648, 28160, 28672, 29184, 29696, 30208, 30720, 31232, 31744, 32256

};

static const uint16_t gau16AGainTable[128] = {
    0x320, 0x321, 0x322, 0x323, 0x324, 0x325, 0x326, 0x327, 0x328, 0x329, 0x32a, 0x32b, 0x32c, 0x32d, 0x32e, 0x32f, 0x330, 0x331, 0x332, 0x333, 0x334, 0x335, 0x336, 0x337, 0x338, 0x339, 0x33a, 0x33b, 0x33c, 0x33d, 0x33e, 0x33f,
    0x720, 0x721, 0x722, 0x723, 0x724, 0x725, 0x726, 0x727, 0x728, 0x729, 0x72a, 0x72b, 0x72c, 0x72d, 0x72e, 0x72f, 0x730, 0x731, 0x732, 0x733, 0x734, 0x735, 0x736, 0x737, 0x738, 0x739, 0x73a, 0x73b, 0x73c, 0x73d, 0x73e, 0x73f,
    0xf20, 0xf21, 0xf22, 0xf23, 0xf24, 0xf25, 0xf26, 0xf27, 0xf28, 0xf29, 0xf2a, 0xf2b, 0xf2c, 0xf2d, 0xf2e, 0xf2f, 0xf30, 0xf31, 0xf32, 0xf33, 0xf34, 0xf35, 0xf36, 0xf37, 0xf38, 0xf39, 0xf3a, 0xf3b, 0xf3c, 0xf3d, 0xf3e, 0xf3f,
    0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, 0x1f25, 0x1f26, 0x1f27, 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f, 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, 0x1f37, 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d, 0x1f3e, 0x1f3f

};

/*
void cmos_again_calc_table(uint16_t *pu32AgainLin, uint16_t *pu32AgainDb)
{
    int i;

    if (*pu32AgainLin >= gau16GainIndex[127]) {
        *pu32AgainLin = gau16GainIndex[127];
        *pu32AgainDb = gau16AGainTable[127];
        return ;
    }

    for (i = 1; i < 128; i++) {
        if (*pu32AgainLin < gau16GainIndex[i]) {
            *pu32AgainLin = gau16GainIndex[i - 1];
            *pu32AgainDb = gau16AGainTable[i - 1];
                break;
        }
    }

    //printf("%s %d %d %d 0x%x \n",__func__,i,*pu32AgainLin,gau16GainIndex[i - 1],*pu32AgainDb);
    return;
}
*/
#endif 

int sc2355_hw_reset(void)
{
	volatile uint32_t *base;

    sensorHwReset_5(5);
    sensorHwReset(7);

#if 0
	//IR_PWRDN UART1_RTSN GPIOA[21]
    base = (uint32_t *)(CSKY_GPIO0_BASE + 0x04);  //GPIOA direction
    *base |= (0x1 << 21); 
    base = (uint32_t *)(CSKY_GPIO0_BASE + 0x00);  //out
    *base |= (0x1 << 21); //IR_PWRDN

	//IR_RESET AOGPIO7
	base = (uint32_t *)(CSKY_AOGPIO_BASE + 0x04); //gpio dicrection
	*base |= (0x1 << 7);
	base = (uint32_t *)(CSKY_AOGPIO_BASE + 0x00); //output
    *base &= ~(0x1 << 7);
    aos_msleep(1);
	*base |= (0x1 << 7);
#endif 

    return 0;
}



